package com.sky.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealAndDish;
import com.sky.entity.SetmealDish;
import com.sky.exception.DishStatusException;
import com.sky.exception.SetmealNameException;
import com.sky.exception.SetmealStatusException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.SetmealVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @projectName: sky-take-out
 * @package: com.sky.service.impl
 * @className: SetmealServiceImpl
 * @author: Eric
 * @description: TODO
 * @date: 2023/9/22 17:44
 * @version: 1.0
 */
@Service
@RequiredArgsConstructor
public class SetmealServiceImpl implements SetmealService {
    private final SetmealMapper setmealMapper;
    private final SetmealDishMapper setmealDishMapper;
    private final DishMapper dishMapper;
    private final CategoryMapper categoryMapper;

    @Override
    public PageResult pag(SetmealPageQueryDTO setmealPageQueryDTO) {
        PageHelper.startPage(setmealPageQueryDTO.getPage(),setmealPageQueryDTO.getPageSize());
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealPageQueryDTO,setmeal);
        List<Setmeal> setmealList = setmealMapper.selectPag(setmeal);
        PageInfo<Setmeal> pageInfo = new PageInfo<>(setmealList);
        return new PageResult(pageInfo.getTotal(),pageInfo.getList());
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = "SETMEAL_BY_CATEGORYID",key = "#setmealDTO.categoryId")
    public void creatSetmeal(SetmealDTO setmealDTO) {
        Integer count = setmealMapper.getCountByName(setmealDTO.getName());
        if (count>0){
            throw new SetmealNameException(MessageConstant.ERROR_SETMEAL_NAME);
        }
        SetmealAndDish setmealAndDish = new SetmealAndDish();
        BeanUtils.copyProperties(setmealDTO,setmealAndDish);
        setmealMapper.creatSetmeal(setmealAndDish);
        creatSetmealDish(setmealDTO, setmealAndDish);
    }

    @Override
    @CacheEvict(cacheNames = "SETMEAL_BY_CATEGORYID",allEntries = true)
    public void changeStatus(Long id, Integer status) {
        if (Objects.equals(status, StatusConstant.ENABLE)){  // 起售,要判断菜品是否有禁售的
            List<SetmealDish> setmealDish = setmealDishMapper.selectBySetmealId(id);
            Integer countStatus = dishMapper.getCountStatus(setmealDish);
            if (countStatus>0){     // 包含禁售的
                throw new SetmealStatusException(MessageConstant.SETMEAL_ENABLE_FAILED);
            }
        }
        Setmeal setmeal = new Setmeal();
        setmeal.setId(id);
        setmeal.setStatus(status);
        setmealMapper.changeStatus(setmeal);
    }

    @Override
    public SetmealVO getSetmeal(Long id) {
        SetmealVO setmealVO = setmealMapper.getSetmeal(id);
        String categoryName = categoryMapper.getNameByCategoryId(setmealVO.getCategoryId());
        setmealVO.setCategoryName(categoryName);
        List<SetmealDish> setmealDishList = setmealDishMapper.selectById(id);
        setmealVO.setSetmealDishes(setmealDishList);
        return setmealVO;
    }

    @Override
    @Transactional
    public void deleteByIds(String ids) {
        List<Long> idsList = Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList());
        Integer statusCount = setmealMapper.getCountByIds(idsList);
        if (statusCount>0){     // 包含起售的
            throw new SetmealStatusException(MessageConstant.SETMEAL_ON_SALE);
        }
        setmealDishMapper.deleteByIdsList(idsList);
        setmealMapper.deleteByIdsList(idsList);
    }

    @Override
    @Transactional
    @CacheEvict(cacheNames = "SETMEAL_BY_CATEGORYID",key = "#setmealDTO.categoryId")
    public void updateSetmeal(SetmealDTO setmealDTO) {
        SetmealAndDish setmealAndDish = new SetmealAndDish();
        BeanUtils.copyProperties(setmealDTO,setmealAndDish);
        setmealMapper.updateSetmeal(setmealAndDish);
        setmealDishMapper.deleteByIdsList(Collections.singletonList(setmealAndDish.getId()));
        creatSetmealDish(setmealDTO,setmealAndDish);
    }

    @Override
    @Cacheable(cacheNames = "SETMEAL_BY_CATEGORYID",key = "#categoryId")
    public List<SetmealVO> selectByCategoryId(Long categoryId) {
        List<Setmeal> setmealList = setmealMapper.selectByCategoryId(categoryId);
        List<SetmealVO> setmealVOList = new ArrayList<>();
        for (Setmeal setmeal : setmealList) {
            SetmealVO setmealVO = new SetmealVO();
            BeanUtils.copyProperties(setmeal,setmealVO);
            setmeal.setCategoryId(setmealVO.getCategoryId());
            setmeal.setCreateTime(setmealVO.getUpdateTime());
            setmeal.setUpdateTime(setmealVO.getUpdateTime());
            setmeal.setCreateUser(setmealVO.getCategoryId());
            setmeal.setUpdateUser(setmealVO.getCategoryId());
            setmealVOList.add(setmealVO);
        }
        return setmealVOList;
    }

    /**
     * 创建套餐
     *
     * @param setmealDTO     setmeal dto
     * @param setmealAndDish 套餐和菜肴
     */
    private void creatSetmealDish(SetmealDTO setmealDTO, SetmealAndDish setmealAndDish) {
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        Integer statusCount = dishMapper.getCountStatus(setmealDishes);
        if (statusCount>0){     // 说明存在停售的
            throw new DishStatusException(MessageConstant.SETMEAL_ENABLE_FAILED);
        }
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(setmealAndDish.getId());
        }
        setmealDishMapper.creatSetmealDish(setmealDishes);
    }
}
